package com.boring.serialport


import android.content.Context
import android.os.Bundle
import android.serialport.SerialPortFinder
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.Checkbox
import androidx.compose.material.Divider
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.PopupProperties
import com.example.serialtool.SerialPortManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

private const val TAG = "MainActivity"
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SerialTool()
        }
    }
}



@Composable
fun SerialTool() {
    val coroutineScope = rememberCoroutineScope()
    val context = LocalContext.current

    val sharedPreferences = context.getSharedPreferences("SerialToolPrefs", Context.MODE_PRIVATE)
    val savedPort = sharedPreferences.getString("lastPort", null)

    var serialPortManager = remember { SerialPortManager() }
    var selectedPort by remember { mutableStateOf<String?>(savedPort) }
    var baudRate by remember { mutableStateOf(9600) }
    var receivedDataList by remember { mutableStateOf(listOf<Pair<String, String>>()) }
    var sendData by remember { mutableStateOf("FF55012388") }
    var commonDataList by remember { mutableStateOf(listOf<String>()) }
    var sendHistoryExpanded by remember { mutableStateOf(false) }
    var sendHistoryList by remember { mutableStateOf(listOf<String>()) }
    var sendInterval by remember { mutableStateOf(1000L) } // 默认为1秒
    var isScheduledSendEnabled by remember { mutableStateOf(false) }

    val baudRates = listOf(9600, 19200, 38400, 57600, 115200)

    var isPortDropdownExpanded by remember { mutableStateOf(false) }
    var isBaudRateDropdownExpanded by remember { mutableStateOf(false) }
    var isHexMode by remember { mutableStateOf(true) }
    var isSerialPortOpen by remember { mutableStateOf(false) }
    var isSendingEnabled by remember { mutableStateOf(false) }

    val lazyListState = rememberLazyListState()

    LaunchedEffect(Unit) {
        if (selectedPort == null) {
            val serialPorts = getAllDevicesPath()
            if (serialPorts.isNotEmpty()) {
                selectedPort = serialPorts.first()
            }
        }
    }

    Column(modifier = Modifier
        .fillMaxSize()
        .padding(16.dp)) {
        Row(modifier = Modifier
            .weight(1f)
            .fillMaxSize()) {
            // 接收到的数据展示区域，占据左侧
            Column(modifier = Modifier
                .weight(4f)
                .padding(end = 16.dp)) {
                Text("接收到的数据:", style = MaterialTheme.typography.h6)
                Divider(color = Color.Magenta)
                LazyColumn(modifier = Modifier.weight(1f), state = lazyListState) {
                    items(receivedDataList.size) { index ->
                        val (time, data) = receivedDataList[index]
                        Row(modifier = Modifier
                            .fillMaxWidth()
                            .border(1.dp, Color.Gray)
                            .padding(8.dp)) {
                            Text("时间: $time", fontSize = 12.sp, color = Color.DarkGray, modifier = Modifier.weight(1f))
                            Text("数据: $data", fontSize = 14.sp, modifier = Modifier.weight(3f))
                        }
                    }
                }
            }

            Box (modifier = Modifier.padding(top = 5.dp, bottom = 5.dp).fillMaxHeight()){
                Divider(color = Color.Magenta, modifier = Modifier.width(1.dp))
            }
            // 控制区，占据右侧
            Column(modifier = Modifier.weight(1f)) {
                // 串口地址选择
                Box {
                    Text(
                        text = selectedPort ?: "选择串口",
                        modifier = Modifier
                            .fillMaxWidth()
                            .clickable { isPortDropdownExpanded = true }
                            .border(1.dp, Color.Gray)
                            .padding(16.dp)
                    )
                    DropdownMenu(
                        expanded = isPortDropdownExpanded,
                        onDismissRequest = { isPortDropdownExpanded = false },
                        properties = PopupProperties(focusable = true)
                    ) {
                        val serialPorts = getAllDevicesPath()
                        serialPorts.forEach { port ->
                            DropdownMenuItem(onClick = {
                                selectedPort = port
                                isPortDropdownExpanded = false
                                sharedPreferences.edit().putString("lastPort", port).apply()
                            }) {
                                Text(port)
                            }
                        }
                    }
                }

                Spacer(modifier = Modifier.height(8.dp))

                // 波特率选择
                Box {
                    Text(
                        text = baudRate.toString(),
                        modifier = Modifier
                            .fillMaxWidth()
                            .clickable { isBaudRateDropdownExpanded = true }
                            .border(1.dp, Color.Gray)
                            .padding(16.dp)
                    )
                    DropdownMenu(
                        expanded = isBaudRateDropdownExpanded,
                        onDismissRequest = { isBaudRateDropdownExpanded = false },
                        properties = PopupProperties(focusable = true)
                    ) {
                        baudRates.forEach { rate ->
                            DropdownMenuItem(onClick = {
                                baudRate = rate
                                isBaudRateDropdownExpanded = false
                            }) {
                                Text(rate.toString())
                            }
                        }
                    }
                }

                Spacer(modifier = Modifier.height(8.dp))

                // 打开/关闭串口按钮
                Button(onClick = {
                    if (isSerialPortOpen) {
                        serialPortManager.close()
                        isSerialPortOpen = false
                        isSendingEnabled = false
                        isScheduledSendEnabled = false
                    } else {
                        selectedPort?.let { port ->
                            if (serialPortManager.open(port, baudRate)) {
                                isSerialPortOpen = true
                                isSendingEnabled = true
                            }
                        }
                    }
                }, Modifier.fillMaxWidth()) {
                    Text(if (isSerialPortOpen) "关闭串口" else "打开串口")
                }

                Spacer(modifier = Modifier.height(8.dp))

                // 16进制发送和接收选择
                Row(verticalAlignment = Alignment.CenterVertically) {
                    Checkbox(
                        checked = isHexMode,
                        onCheckedChange = {
                            isHexMode = it
                            if(isHexMode){
                                sendData ="FF55012388"
                            }else{
                                sendData ="AT+V\n"
                            }
                        }
                    )
                    Text("以16进制发送和接收")
                }

                Spacer(modifier = Modifier.height(8.dp))

                // 定时发送开关
                Row(verticalAlignment = Alignment.CenterVertically) {
                    Checkbox(
                        checked = isScheduledSendEnabled,
                        onCheckedChange = { enabled ->
                            isScheduledSendEnabled = enabled
                            if (!enabled) {
                                // 如果定时发送被禁用，取消所有定时任务
                                commonDataList.forEach { data ->
                                    // 清理定时发送任务
                                }
                            }
                        }
                    )
                    Text("启用定时发送")
                }

                Spacer(modifier = Modifier.height(8.dp))

                // 定时发送间隔时间输入框
                if (isScheduledSendEnabled) {
                    var intervalText by remember { mutableStateOf(sendInterval.toString()) }
                    BasicTextField(
                        value = intervalText,
                        onValueChange = { intervalText = it },
                        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                        modifier = Modifier
                            .fillMaxWidth()
                            .border(1.dp, Color.Gray)
                            .padding(8.dp)
                    )
                    Spacer(modifier = Modifier.height(4.dp))
                    Button(onClick = {
                        sendInterval = intervalText.toLongOrNull() ?: 1000L
                    }) {
                        Text("设置间隔时间")
                    }
                }

                // 清除接收数据按钮
                Button(onClick = {
                    receivedDataList = listOf()
                }) {
                    Text("清除接收数据")
                }
            }
        }

        Box (modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)){
            Divider(color = Color.Magenta)
        }
        // 发送数据输入框和发送按钮，放置在最底部
        Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
            BasicTextField(
                value = sendData,
                onValueChange = { sendData = it },
                modifier = Modifier
                    .weight(1f)
                    .height(56.dp)
                    .border(1.dp, Color.Gray)
                    .padding(8.dp)
            )
            Spacer(modifier = Modifier.width(8.dp))
            Button(
                onClick = {
                    if (isSendingEnabled) {
                        if (!commonDataList.contains(sendData)) {
                            commonDataList = commonDataList + sendData
                        }
                        coroutineScope.launch {
                            selectedPort?.let { port ->
                                if (serialPortManager.open(port, baudRate)) {
                                    serialPortManager.write(if (isHexMode) hexStringToByteArray(sendData) else sendData.toByteArray())
                                }
                            }
                        }
                        // 添加到发送历史
//                        sendHistoryList = sendHistoryList + sendData
                    }
                },
                enabled = isSendingEnabled,
                modifier = Modifier
                    .width(100.dp)
                    .height(48.dp)
            ) {
                Text("发送")
            }
            Spacer(modifier = Modifier.width(8.dp))
            Button(onClick = { sendHistoryExpanded = !sendHistoryExpanded }
                ,  modifier = Modifier
                    .width(100.dp)
                    .height(48.dp)) {
                Text("发送历史")
            }
        }

        Spacer(modifier = Modifier.height(16.dp))

        // 显示发送历史下拉列表
        DropdownMenu(
            expanded = sendHistoryExpanded,
            onDismissRequest = { sendHistoryExpanded = false }
        ) {
            commonDataList.forEach { data ->
                DropdownMenuItem(onClick = {
                    sendData = data
                    sendHistoryExpanded = false
                }) {
                    Text(data)
                }
            }
        }

    }

    LaunchedEffect(selectedPort, isSerialPortOpen) {
        if (isSerialPortOpen) {
            selectedPort?.let { port ->
                coroutineScope.launch(Dispatchers.IO) {
                    val buffer = ByteArray(1024) // 增大缓存区大小
                    try {
                        serialPortManager.open(port, baudRate)
                        while (isSerialPortOpen) {
                            val len = serialPortManager.read(buffer)
                            if (len > 0) {
                                val dataBytes = buffer.copyOf(len)
                                val data = if (isHexMode) bytesToHex(dataBytes) else String(dataBytes, charset("GBK"))
                                val currentTime = SimpleDateFormat("HH:mm:ss:SSS", Locale.getDefault()).format(Date())

                                // 处理换行符
                                val lines = data.split("\n")
                                val newDataList = lines.map { line -> Pair(currentTime, line) }

                                withContext(Dispatchers.Main) {
                                    receivedDataList = receivedDataList + newDataList
                                    coroutineScope.launch {
                                        lazyListState.animateScrollToItem(receivedDataList.size - 1)
                                    }
                                }
                            }
                        }
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                }
            }
        }
    }

    // 定时发送逻辑
    DisposableEffect(isScheduledSendEnabled, sendInterval) {
        val job = CoroutineScope(Dispatchers.IO).launch {
            while (isScheduledSendEnabled) {
                delay(sendInterval)
                if (isSendingEnabled) {
                    selectedPort?.let { port ->
                        serialPortManager.write(if (isHexMode) hexStringToByteArray(sendData) else sendData.toByteArray())
                    }
                }
            }
        }

        onDispose {
            job.cancel()
        }
    }
}




fun getAllDevicesPath(): Array<String> {
    return SerialPortFinder().allDevicesPath
}

fun hexStringToByteArray(s: String): ByteArray {
    // 移除所有空格
    val cleanedString = s.replace(" ", "")
    // 如果长度是奇数，则在前面补充一个0
    val hexString = if (cleanedString.length % 2 != 0) "0$cleanedString" else cleanedString
    val len = hexString.length
    val data = ByteArray(len / 2)
    for (i in 0 until len step 2) {
        data[i / 2] = ((Character.digit(hexString[i], 16) shl 4) + Character.digit(hexString[i + 1], 16)).toByte()
    }
    return data
}


fun bytesToHex(bytes: ByteArray): String {
    return bytes.joinToString(" ") { String.format("%02X", it) }
}
